from __future__ import annotations
import json
import numpy as np
import os
from django.shortcuts import render
from django.http import JsonResponse, HttpResponse
from .models import *
import uuid
from django.views.decorators.csrf import csrf_protect, csrf_exempt
from .carbonReductionAssessment import evaluate

Admin_statue = [4]
Enterprise_statue = [3]

ParentZoneMapping = {
    'North': [11, 12, 13, 14, 37, 15],  # 北京11 天津12 河北13 山西14 山东37 内蒙古15
    'Northeast': [21, 22, 23, 15],  # 辽宁21 吉林22 黑龙江23 内蒙古15
    'East': [31, 32, 33, 34, 35],  # 上海31 江苏32 浙江33 安徽34 福建35
    'Central': [41, 42, 43, 36, 51, 50],  # 河南41 湖北42 湖南43 江西36 四川51 重庆50
    'Northwest': [61, 62, 63, 64, 65],  # 陕西61 甘肃62 青海63 宁夏64 新疆65
    'South': [44, 45, 53, 52, 46]  # 广东44 广西45 云南53 贵州52 海南46
}


# 西藏54 台湾71 香港81 澳门82

# Create your views here.
def home(request):
    return HttpResponse('home')


def queryset2list(quaryset):
    result = []
    for i in quaryset.values():
        result.append(i)
    return result


@csrf_exempt
def login(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    phone = data.get('phone', '')
    psd = data.get('password', '')

    try:
        user = User.objects.get(phone=phone)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if user.password == psd:
        return JsonResponse({'status': 'success', 'uuid': str(user.uuid), 'name': user.name, 'user_status': user.status})
    else:
        return JsonResponse({'status': 'error', 'message': 'Password error'}, status=400)


@csrf_exempt
def add_user(request):
    '''
    Adds a user to the Model
    '''
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)

        # 从解析后的数据中获取用户信息
        name = data.get('name', '')
        region = data.get('region', '')
        phone = data.get('phone', '')
        for key in ParentZoneMapping.keys():
            if int(region['province'][:2]) in ParentZoneMapping[key]:
                ParentZone = key
                break
        password = data.get('password', '')
        is_expert = data.get('is_expert', False)
        status = data.get('status', 1)
        company = data.get('company', '')
        legal = data.get('legal', '')


        user_list = User.objects.filter(phone=phone)

        if user_list: 
            return JsonResponse({'status': 'error', 'message': 'User is exist'}, status=400)

        # 创建并保存用户实例
        user = User(
            uuid=uuid.uuid4(),  # 自动生成UUID
            name=name,
            phone=phone,
            region=json.dumps(region),
            ParentZone=ParentZone,
            password=password,
            is_expert=is_expert,
            status=status,
            company=company,
            legal=legal
        )
        print(user.name)
        user.save()

        # 返回成功响应
        return JsonResponse({'status': 'success', 'uuid': str(user.uuid)})

    # 如果不是POST请求，则返回错误响应
    return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

def _get_user_info(uuid):
    user_list = queryset2list(User.objects.filter(uuid=uuid))
    for user_info in user_list:
        user_info['region'] = json.loads(user_info['region'])
    return user_list

@csrf_exempt
def get_user_info(request):
    '''
    Adds a user to the Model
    '''
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')

    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)
    
    return JsonResponse({'status': 'success', 'userinfo': _get_user_info(uuid)})


@csrf_exempt
def change_user_info(request):
    '''
    Adds a user to the Model
    '''
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')

    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    name = data.get('name', user.name)
    region = data.get('region', user.region)
    for key in ParentZoneMapping.keys():
        if int(region['province'][:2]) in ParentZoneMapping[key]:
            ParentZone = key
            break
    
    password = data.get('password', user.password)
    phone = data.get('phone', user.phone)

    user_list = User.objects.filter(phone=phone)

    if len(user_list) >= 1 and user_list[0].uuid != user.uuid: 
        return JsonResponse({'status': 'error', 'message': 'Phone is used'}, status=400)


    user.name = name
    user.region = json.dumps(region)
    user.ParentZone = ParentZone
    user.password = password
    user.phone = phone

    user.save()
    return JsonResponse({'status': 'success', 'uuid': str(user.uuid)})


@csrf_exempt
def confirm_enterprise_user(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')

    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if user.status not in Enterprise_statue:
        return JsonResponse({'status': 'error', 'message': 'User is not enterprise user'}, status=404)
    else:
        user.is_registered = True
        user.save()
        return JsonResponse({'status': 'success', 'uuid': str(user.uuid)})


@csrf_exempt
def get_all_user(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')
    

    # 查找匹配的User实例
    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if user.status in Admin_statue:
        # 获取所有user
        user_list = User.objects.all()
        user_list = queryset2list(user_list)
        for user_info in user_list:
            user_info['region'] = json.loads(user_info['region'])

        return JsonResponse({'status': 'success', 'data': user_list})
    else:
        return JsonResponse({'status': 'error', 'message': 'User status error'}, status=404)


@csrf_exempt
def get_all_unregistered_user(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')

    # 查找匹配的User实例
    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if user.status in Admin_statue:
        # 获取所有未注册user
        user_list = User.objects.filter(status=3, is_registered=False)
        user_list = queryset2list(user_list)

        return JsonResponse({'status': 'success', 'data': user_list})
    else:
        return JsonResponse({'status': 'error', 'message': 'User status error'}, status=404)


@csrf_exempt
def add_suggest(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)

        # 从解析后的数据中获取用户信息
        message = data.get('message', '')
        user_uuid = data.get('uuid', '')

        # 查找匹配的User实例
        try:
            user = User.objects.get(uuid=user_uuid)
        except User.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

        # 创建并保存Suggestion实例
        suggestion = Suggestion()
        suggestion.message = message
        suggestion.applicants = user  # 将查找到的User实例分配给applicants
        suggestion.save()

        return JsonResponse({'status': 'success', 'uuid': str(suggestion.id)})

    # 如果不是POST请求，则返回错误响应
    return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)


@csrf_exempt
def get_all_suggest(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')

    # 查找匹配的User实例
    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if user.status in Admin_statue:
        # 获取所有suggest
        suggest_list = Suggestion.objects.all()
        suggest_list = queryset2list(suggest_list)

        for suggest in suggest_list:
            # 查找匹配的User实例
            try:
                user = User.objects.get(uuid=suggest['applicants_id'])
            except User.DoesNotExist:
                pass
            suggest['name'] = user.name
        return JsonResponse({'status': 'success', 'data': suggest_list})
    else:
        return JsonResponse({'status': 'error', 'message': 'User status error'}, status=404)


@csrf_exempt
def get_result(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)

        # 从解析后的数据中获取实例信息
        eva_code = data.get('eva_code', '')

        try:
            evaluate = Evaluate.objects.get(uuid=eva_code)
        except Evaluate.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': 'Evaluate not found'}, status=404)

        with open(evaluate.csv_path, 'r') as file:
            print(evaluate.csv_path)
            eva_result = json.load(file)
        return JsonResponse(
            {'status': 'success', 'eva_result': eva_result, 'eva_name': evaluate.name, 'eva_date': evaluate.date})


@csrf_exempt
def get_result_list(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    user_uuid = data.get('uuid', '')
    option = data.get('option', 'self')

    # 查找匹配的User实例
    try:
        user = User.objects.get(uuid=user_uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if option == 'self':
        # 查找匹配的Evaluate实例列表
        eva_list = Evaluate.objects.filter(applicants=user_uuid)
    elif option == 'all':
        if user.status in Admin_statue:
            eva_list = Evaluate.objects.all()
        else:
            return JsonResponse({'status': 'error', 'message': 'User status error'}, status=404)
    elif option == 'region':
        if user.status in Enterprise_statue:
            eva_list = Evaluate.objects.filter(applicants__ParentZone=user.ParentZone)
        else:
            return JsonResponse({'status': 'error', 'message': 'User status error'}, status=404)
    else:
        return JsonResponse({'status': 'error', 'message': 'Option error'}, status=404)

    eva_list = queryset2list(eva_list)
    return JsonResponse({'status': 'success', 'eva_list': eva_list})


def get_factor_wights(name_list: list | str) -> list | float:
    if type(name_list) is list:
        wights_list = []
        for name in name_list:
            wights_list.append(get_factor_wights(name))
        return wights_list
    elif type(name_list) is str:
        return Admin.objects.get(factor=name_list).value


@csrf_exempt
def change_factors(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    data = data.get('factors', {})
    for key in data.keys():
        try:
            factor = Admin.objects.get(factor=key)
        except Admin.DoesNotExist:
            return JsonResponse({'status': 'error', 'message': 'Factors not found'}, status=404)
        factor.value = data[key]
        factor.save()

    return JsonResponse({'status': 'success', 'data': _get_all_factor()})


def _get_all_factor() -> list:
    return queryset2list(Admin.objects.all())


@csrf_exempt
def get_all_factor(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    uuid = data.get('uuid', '')

    # 查找匹配的User实例
    try:
        user = User.objects.get(uuid=uuid)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    if user.status in Admin_statue:
        # 获取所有factor
        factor_list = _get_all_factor()

        return JsonResponse({'status': 'success', 'data': factor_list})
    else:
        return JsonResponse({'status': 'error', 'message': 'User status error'}, status=404)


@csrf_exempt
def evaluate_data(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            original_data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # User information
    user_uuid = original_data.get('uuid', '')
    user = User.objects.get(uuid=user_uuid)
    if user.ParentZone is None:
        return JsonResponse({'status': 'error', 'message': 'User region is not setting'}, status=404)

    evaluate_name = original_data.get('name', '评估测试' + datetime.now().strftime("%Y%m%d-%H%M"))

    # evaluation data
    eva_uuid = uuid.uuid4()
    data = original_data.get('data', '')
    cost_data = []
    cod_tn_data = ['cod_in', 'tn_in', 'cod_out', 'tn_out']
    direct_weight = get_factor_wights(['COD', 'TN', user.ParentZone])
    emission_reduction_data = []
    indirect_data = []
    indirect_weight = []
    for key in data.keys():
        # if key == 'region':
        #     direct_weight.append(get_factor_wights(data[key]))
        if key == 'factory_name':
            factory_list = data[key]
        elif key == 'total_invest':
            total_invest = np.array(data[key]).reshape((-1, 1))
        elif key in ['ele_cost', 'phar_cost', 'empl_cost', 'other_cost']:
            cost_data.append(data[key])
        elif key == 'ele_consum':
            ele_consum = np.array(data[key]).reshape((-1, 1))
        elif key == 'wast_treat':
            wast_treat = np.array(data[key]).reshape((-1, 1))
        elif key in cod_tn_data:
            cod_tn_data[cod_tn_data.index(key)] = data[key]
        elif key in ['cod_redu', 'nh_redu', 'tn_redu', 'tp_redu']:
            emission_reduction_data.append(data[key])
        elif key == 'sludge_prod':
            sludge_prod = np.array(data[key]).reshape((-1, 1))
        else:
            indirect_data.append(data[key])
            indirect_weight.append(get_factor_wights(key))
    cost_data = np.array(cost_data).T
    cod_tn_data = np.array(cod_tn_data).T
    emission_reduction_data = np.array(emission_reduction_data).T
    indirect_data = np.array(indirect_data).T

    result = evaluate(factory_list, total_invest, cost_data, ele_consum, wast_treat, cod_tn_data, direct_weight,
                      emission_reduction_data, sludge_prod, indirect_data, indirect_weight)

    # Save the Evaluate result
    keepFile = {
        "original_input": data,
        "evaluate_result": result
    }
    eva_path = 'estimation/eva_data/' + str(user.uuid)
    if not os.path.exists(eva_path):
        os.makedirs(eva_path)
    eva_file_path = eva_path + '/' + str(eva_uuid) + '.json'
    with open(eva_file_path, 'w') as file:
        json.dump(keepFile, file)

        # 创建并保存测评实例
        eva = Evaluate(
            uuid=eva_uuid,
            name=evaluate_name,
            applicants=user,
            csv_path=eva_file_path
        )
        eva.save()
    return JsonResponse({'status': 'success', 'eva_list': result, "uuid": str(eva_uuid)})


@csrf_exempt
def add_comment(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    post_id = data.get('p_id', '')
    user_id = data.get('u_id', '')
    user_comment = data.get('comment', '')

    # 查找匹配的User实例
    try:
        user = User.objects.get(uuid=user_id)
    except User.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'User not found'}, status=404)

    # 查找匹配的Post实例
    try:
        post = Evaluate.objects.get(uuid=post_id)
    except Evaluate.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'Post not found'}, status=404)

    # 创建并保存Comment实例
    comment = Comment()
    comment.message = user_comment
    comment.user_id = user  # 将查找到的User实例分配给applicants
    comment.post_id = post  # 将查找到的User实例分配给applicants
    comment.save()

    return JsonResponse({'status': 'success', 'uuid': str(comment.id)})


@csrf_exempt
def get_post_all_comment(request):
    if request.method == 'POST':
        # 从请求体中解析JSON数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({'status': 'error', 'message': 'Invalid JSON'}, status=400)
    else:
        # 如果不是POST请求，则返回错误响应
        return JsonResponse({'status': 'error', 'message': 'Only POST method is allowed'}, status=405)

    # 从解析后的数据中获取用户信息
    post_id = data.get('p_id', '')

    # 查找匹配的User实例
    try:
        post = Evaluate.objects.get(uuid=post_id)
    except Evaluate.DoesNotExist:
        return JsonResponse({'status': 'error', 'message': 'Post not found'}, status=404)

    # 查找匹配的Comment实例列表
    post_list = Comment.objects.filter(post_id=post_id)
    post_list_return = queryset2list(post_list)
    for post_return, post in zip(post_list_return, post_list):
        post_return['user_state'] = post.user_id.status
        post_return['user_name'] = post.user_id.name
    return JsonResponse({'status': 'success', 'post_list': post_list_return})
